package cn.ges.ali

import cn.ges.date.DateUtil
import com.taobao.api.DefaultTaobaoClient
import com.taobao.api.TaobaoClient
import com.taobao.api.request.*
import com.taobao.api.response.*
import java.time.LocalDateTime


/**
 *
 * @author gespent@163.com
 * @date 2020/12/1 13:57
 */
class TaoBaoHelper {

    companion object {

        lateinit var appkey: String
        lateinit var secret: String
        var adzoneId: Long? = null


        var url: String = "https://eco.taobao.com/router/rest"
        lateinit var client: DefaultTaobaoClient

        fun initTaoBaoClient(appkey: String, secret: String, url: String?, adzoneId: Long?) {
            TaoBaoHelper.appkey = appkey
            TaoBaoHelper.secret = secret
            url?.let {
                TaoBaoHelper.url = it
            }
            adzoneId?.let {
                TaoBaoHelper.adzoneId = it
            }
            client = DefaultTaobaoClient(Companion.url, Companion.appkey, Companion.secret)
        }

        /**
         * 获得用户AccessToken
         */
        fun getAccessToken(code: String): Pair<Boolean?, String?> {
            val topAuthTokenCreateRequest = TopAuthTokenCreateRequest()
            topAuthTokenCreateRequest.code = code
            // 非必填项
            // topAuthTokenCreateRequest.uuid = ""
            val execute = client.execute(topAuthTokenCreateRequest)
            return execute.isSuccess to execute.tokenResult
        }

        /**
         * second = 邀请码 eg:F8ZQDM
         */
        fun getInviteCode(codeType: Long?, sessionKey: String): Pair<Boolean?, String?> {
            val req = TbkScInvitecodeGetRequest()
            // 	渠道关系ID 不是必填 req.relationId = 11L
            // 渠道推广的物料类型
            req.relationApp = "common"
            // 邀请码类型，1 - 渠道邀请，2 - 渠道裂变，3 -会员邀请
            req.codeType = codeType ?: 3

            val rsp: TbkScInvitecodeGetResponse = client.execute(req, sessionKey)
            return rsp.isSuccess to rsp.data?.inviterCode
        }

        /**
         * 备案私域用户信息
         */
        fun saveUserInfo(sessionKey: String, inviterCode: String, note: String?): Pair<Boolean, TbkScPublisherInfoSaveResponse.Data> {
            val req = TbkScPublisherInfoSaveRequest()
            // 非必填 渠道备案 - 来源，取链接的来源
            // req.relationFrom = "1"
            // 非必填 渠道备案 - 线下场景信息，1 - 门店，2- 学校，3 - 工厂，4 - 其他
            // req.offlineScene = "1"
            // 非必填 渠道备案 - 线上场景信息，1 - 微信群，2- QQ群，3 - 其他
            // req.onlineScene = "1"

            req.inviterCode = inviterCode

            // 类型，必选 默认为1:
            req.infoType = 1L
            // 媒体方信息
            req.note = note
            // 非必填 线下备案注册信息,字段包含: 电话号码(phoneNumber，必填),省(province,必填),市(city,必填),区县街道(location,必填),详细地址(detailAddress,必填),经营类型(career,线下个人必填),店铺类型(shopType,线下店铺必填),店铺名称(shopName,线下店铺必填),店铺证书类型(shopCertifyType,线下店铺选填),店铺证书编号(certifyNumber,线下店铺选填)
            // req.registerInfo = "{\"phoneNumber\":\"18801088599\",\"city\":\"江苏省\",\"province\":\"南京市\",\"location\":\"玄武区花园小区\",\"detailAddress\":\"5号楼3单元101室\",\"shopType\":\"社区店\",\"shopName\":\"全家便利店\",\"shopCertifyType\":\"营业执照\",\"certifyNumber\":\"111100299001\"}"
            val rsp = client.execute(req, sessionKey)
            return rsp.isSuccess to rsp.data
        }

        fun TPwdCreat(url: String) {
            val req = TbkTpwdCreateRequest()
            req.userId = "123"
            req.text = "长度大于5个字符"
            req.url = url
//            req.logo = "https://uland.taobao.com/"
            req.ext = "{}"
            val rsp = client.execute(req)
            println(rsp.body)
        }
        /**
         * 查询用户私域备案信息
         * 需要用户授权 一般不使用
         */
        fun queryUserInfo(sessionKey: String, infoType: Long, relationId: Long?, specialId: String?, externalId: String?): Pair<Boolean, TbkScPublisherInfoGetResponse.Data> {

            val req = TbkScPublisherInfoGetRequest()
            // 必选 1:渠道信息；2:会员信息
            req.infoType = infoType
            // 非必选 渠道独占 - 渠道关系ID
            req.relationId = relationId
            req.pageNo = 1L
            req.pageSize = 10L
            // 固定值
            req.relationApp = "common"
            // 非必填 会员独占 - 会员运营ID
            req.specialId = specialId
            // 非必填	淘宝客外部用户标记，如自身系统账户ID；微信ID等
            req.externalId = externalId
            val rsp = client.execute(req, sessionKey)
            return rsp.isSuccess to rsp.data
        }

        /**
         * 获得活动转链
         */
        fun getActiveLink(activeId: String, adzoneId: Long, relationId: Long?, unionId: String?): Pair<Boolean?, TbkActivityInfoGetResponse.Data?> {
            val req = TbkActivityInfoGetRequest()
            // mm_xxx_xxx_xxx的第三位
            req.adzoneId = adzoneId
            // 非必填 mm_xxx_xxx_xxx 仅三方分成场景使用
            // req.subPid = "mm_1_2_3"
            // 非必填 渠道关系id
            req.relationId = relationId
            // 官方活动会场ID
            req.activityMaterialId = activeId
            req.unionId = unionId
            val rsp = client.execute(req)
            return rsp.isSuccess to rsp.data
        }

        /**
         * 物料搜索
         */
        fun getItem(info: ItemOptional): Pair<Boolean, MutableList<TbkDgMaterialOptionalResponse.MapData>> {
            val req = info.buildReq()
            val rsp = client.execute(req)
            return rsp.isSuccess to rsp.resultList
        }

        fun getItemByMaterial(size:Long,Page:Long,materialId:Long,deviceValue:String?,deviceType:String?): Pair<Boolean, MutableList<TbkDgOptimusMaterialResponse.MapData>> {

            val req = TbkDgOptimusMaterialRequest()
            req.pageSize = size
            req.adzoneId = adzoneId
            req.pageNo = Page
            req.materialId = materialId
            deviceValue?.let {
                value->
                deviceType?.let {
                   if (it!="OAID"){
                       // 智能匹配-设备号加密类型：MD5，类型为OAID时不传
                       req.deviceEncrypt = "MD5"
                   }
                    // IMEI OAID
                    req.deviceType = it
                    req.deviceValue = value
                }
            }
            // 内容专用-内容详情ID
            // req.contentId = 323L
            // 内容专用-内容渠道信息
            // req.contentSource = "xxx"
            // 商品ID，用于相似商品推荐
            // req.itemId = 33243L
            // 选品库投放id
            // req.favoritesId = "123445"
            val rsp = client.execute(req)
            return rsp.isSuccess to rsp.resultList
        }


        /**
         * startTime endTime 应该不超过20分钟
         */
        fun getOrder(startTime: LocalDateTime, endTime: LocalDateTime,
                     tkStatus:Long?,
                     queryType:Long?,
                     memberType:Long?,
                     positionIndex:String?,
                     page: Long?,
                     pageSize:Long?,
                     orderScene: Long?): TbkOrderDetailsGetResponse {

            val req = TbkOrderDetailsGetRequest()
            // 查询时间类型，1：按照订单淘客创建时间查询，2:按照订单淘客付款时间查询，3:按照订单淘客结算时间查询
            req.queryType = queryType ?: 1L
            // 页大小，默认20，1~100
            req.pageSize = pageSize
            // 推广者角色类型,2:二方，3:三方，不传，表示所有角色
            req.memberType = memberType
            // 淘客订单状态，12-付款，13-关闭，14-确认收货，3-结算成功;不传，表示所有状态
            req.tkStatus = tkStatus
            // true 订单查询结束时间，订单开始时间至订单结束时间，中间时间段日常要求不超过3个小时，但如618、双11、年货节等大促期间预估时间段不可超过20分钟，超过会提示错误，调用时请务必注意时间段的选择，以保证亲能正常调用！
            req.endTime = DateUtil.dateToStringWithHms(endTime)
            // true 订单查询开始时间
            req.startTime = DateUtil.dateToStringWithHms(startTime)
            // 跳转类型，当向前或者向后翻页必须提供,-1: 向前翻页,1：向后翻页
            req.jumpType = 1L

            if (positionIndex == null) {
                req.pageNo = 1L
            } else {
                // 第几页，默认1，1~100
                req.pageNo = page
                // 位点，除第一页之外，都需要传递；前端原样返回。
                req.positionIndex = positionIndex
            }

            // 场景订单场景类型，1:常规订单，2:渠道订单，3:会员运营订单，默认为1
            req.orderScene = orderScene ?: 3L

            return client.execute(req)
        }

    }


    class ItemOptional {
        //  商品筛选(特定媒体支持)-店铺dsr评分。筛选大于等于当前设置的店铺dsr评分的商品0-50000之间
        var startDsr: Long? = null

        //  页大小，默认20，1~100
        var pageSize = 20L

        //  第几页，默认：１
        var pageNo = 1L

        //  链接形式：1：PC，2：无线，默认：１
        var platform = 1L

        //  商品筛选-淘客佣金比率上限。如：1234表示12.34%
        var endTkRate: Long? = null

        //  商品筛选-淘客佣金比率下限。如：1234表示12.34%
        var startTkRate: Long? = null

        //  商品筛选-折扣价范围上限。单位：元
        var endPrice: Long? = null

        //  商品筛选-折扣价范围下限。单位：元
        var startPrice: Long? = null

        //  商品筛选-是否海外商品。true表示属于海外商品，false或不设置表示不限
        var isOverseas = false

        // 	商品筛选-是否天猫商品。true表示属于天猫商品，false或不设置表示不限
        var isTmall = false

        //  排序_des（降序），排序_asc（升序），销量（total_sales），淘客佣金比率（tk_rate）， 累计推广量（tk_total_sales），总支出佣金（tk_total_commi），价格（price）
        var sort = "tk_rate_des"

        //  商品筛选-所在地
        var itemloc: String? = null

        // 商品筛选-后台类目ID。用,分割，最大10个，该ID可以通过taobao.itemcats.get接口获取到
        var cat: String? = null

        //  商品筛选-查询词
        var q: String? = null

        // 	不传时默认物料id=2836；如果直接对消费者投放，可使用官方个性化算法优化的搜索物料id=17004
        var materialId = 17004L

        // 优惠券筛选-是否有优惠券。true表示该商品有优惠券，false或不设置表示不限
        var hasCoupon = true

        // ip参数影响邮费获取，如果不传或者传入不准确，邮费无法精准提供
        var ip: String? = null

        // true mm_xxx_xxx_12345678三段式的最后一段数字
        var adzoneId = TaoBaoHelper.adzoneId

        // 商品筛选-是否包邮。true表示包邮，false或不设置表示不限
        var needFreeShipment = false

        // 商品筛选-是否加入消费者保障。true表示加入，false或不设置表示不限
        var needPrepay = false

        // 商品筛选(特定媒体支持)-成交转化是否高于行业均值。True表示大于等于，false或不设置表示不限
        var includePayRate30 = false

        // 商品筛选-好评率是否高于行业均值。True表示大于等于，false或不设置表示不限
        var includeGoodRate = false

        // 商品筛选(特定媒体支持)-退款率是否低于行业均值。True表示大于等于，false或不设置表示不限
        var includeRfdRate = false

        // 商品筛选-牛皮癣程度。取值：1不限，2无，3轻微
        var npxLevel = 1L

        // 商品筛选-KA媒体淘客佣金比率上限。如：1234表示12.34%
        var endKaTkRate: Long? = null

        // 商品筛选-KA媒体淘客佣金比率下限。如：1234表示12.34%
        var startKaTkRate: Long? = null

        // 智能匹配-设备号加密类型：MD5
        var deviceEncrypt: String? = null

        // 智能匹配-设备号加密后的值（MD5加密需32位小写）
        var deviceValue: String? = null


        // 智能匹配-设备号类型：IMEI，或者IDFA，或者UTDID（UTDID不支持MD5加密），或者OAID
        var deviceType: String? = null

        // 	锁佣结束时间
        var lockRateEndTime: Long? = null

        // 锁佣开始时间
        var lockRateStartTime: Long? = null

        // 本地化业务入参-LBS信息-经度"121.473701"
        var longitude: String? = null

        // 本地化业务入参-LBS信息-纬度 "31.230370"
        var latitude: String? = null

        // 本地化业务入参-LBS信息-国标城市码，仅支持单个请求，请求饿了么卡券物料时，该字段必填。 （详细城市ID见：https://mo.m.taobao.com/page_2020010315120200508）
        var cityCode: String? = null

        // 商家id，仅支持饿了么卡券商家ID，支持批量请求1-100以内，多个商家ID使用英文逗号分隔 "1,2,3,4"
        var sellerIds: String? = null

        // 	会员运营ID
        var specialId: String? = null

        // 渠道关系ID
        var relationId: String? = null

        fun buildReq(): TbkDgMaterialOptionalRequest {
            return TbkDgMaterialOptionalRequest().let {
                it.startDsr = startDsr
                it.pageSize = pageSize
                it.pageNo = pageNo
                it.platform = platform
                it.endTkRate = endTkRate
                it.startTkRate = startTkRate
                it.endPrice = endPrice
                it.startPrice = startPrice
                it.isOverseas = isOverseas
                it.isTmall = isTmall
                it.sort = sort
                it.itemloc = itemloc
                it.cat = cat
                it.q = q
                it.materialId = materialId
                it.hasCoupon = hasCoupon
                it.ip = ip
                it.adzoneId = adzoneId
                it.needFreeShipment = needFreeShipment
                it.needPrepay = needPrepay
                it.includePayRate30 = includePayRate30
                it.includeGoodRate = includeGoodRate
                it.includeRfdRate = includeRfdRate
                it.npxLevel = npxLevel
                it.endKaTkRate = endKaTkRate
                it.startKaTkRate = startKaTkRate
                it.deviceEncrypt = deviceEncrypt
                it.deviceValue = deviceValue
                it.deviceType = deviceType
                it.lockRateEndTime = lockRateEndTime
                it.lockRateStartTime = lockRateStartTime
                it.longitude = longitude
                it.latitude = latitude
                it.cityCode = cityCode
                it.sellerIds = sellerIds
                it.specialId = specialId
                it.relationId = relationId
                it
            }
        }
    }

}